﻿// 线程池项目-自己.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

#include <iostream>
#include <chrono>
#include <thread>
#include "threadpool.h"

using namespace std;

/*
有些场景，是希望能够获取线程执行任务得返回值得
举例：
1 + 。。。 + 30000的和
thread1  1 + ... + 10000
thread2  10001 + ... + 20000
.....

main thread：给每一个线程分配计算的区间，并等待他们算完返回结果，合并最终的结果即可
*/

using uLong = unsigned long long;

class MyTask : public Task
{
public:
    MyTask(int begin, int end)
        :begin_(begin)
        , end_(end)
    {}
    Any run()  // run方法最终就在线程池分配的线程中去做执行了!
    {
        std::cout << "tid:" << std::this_thread::get_id()
            << "begin!" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(3));
        uLong sum = 0;
        for (uLong i = begin_; i <= end_; i++)
            sum += i;
        std::cout << "tid:" << std::this_thread::get_id()
            << "end!" << std::endl;

        return sum;
    }
private:
    int begin_;
    int end_;
};
    // 问题一：怎么设计run函数的返回值，可以表示任意的类型
// Java Python   Object 是所有其它类类型的基类
// C++17 Any类型
   
/*
如何让线程池提交任务更方便 原来需要先来一个智能指针，
指向自己定义的派生类，用户向派生类传参 
*/
 

int main()
{

    ThreadPool pool;
    pool.setMode(PoolMode::MODE_CACHED);
    // 开始启动线程池
    pool.start(2);

    // linux上，这些Result对象也是局部对象，要析构的！！！
    Result res1 = pool.submitTask(std::make_shared<MyTask>(1, 100000000));
    Result res2 = pool.submitTask(std::make_shared<MyTask>(100000001, 200000000));
    pool.submitTask(std::make_shared<MyTask>(100000001, 200000000));
    pool.submitTask(std::make_shared<MyTask>(100000001, 200000000));
    pool.submitTask(std::make_shared<MyTask>(100000001, 200000000));

#if 0
    ThreadPool pool;
    //用户自己设置线程池工作模式
    pool.setMode(PoolMode::MODE_CACHED);
    //开始启动线程池
    pool.start(4);

    //有返回值类型的任务，如何设计result机制，把result和MyTask绑定起来
    Result res = pool.submitTask(std::make_shared<MyTask>(1,100000));

    //随着task被执行完，task对象没了，依赖于task的result对象也没了
    uLong sum1 = res.get().cast_<uLong>();
    pool.submitTask(std::make_shared<MyTask>());
    pool.submitTask(std::make_shared<MyTask>());
    pool.submitTask(std::make_shared<MyTask>());
    pool.submitTask(std::make_shared<MyTask>());
    pool.submitTask(std::make_shared<MyTask>());
    getchar();
    /*getchar(); 是 “读取字符” 的函数，不是专门用来退出程序的。
常见关联场景：
让程序暂停，等用户手动输入后再退出（辅助看运行结果）。
结合条件判断，用读取的字符触发 return/exit 来退出程序（但退出动作由其他语句完成 ）。*/
}
#endif
